/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package testing;

import cfar.actors.Node;
import cfar.actors.distributed.ActorServer;
import cfar.ff.data.Assocs.Assoc2;
import cfar.ff.data.List;
import cfar.ff.fun.F1;
import cfar.ff.fun.Seq;
import cfar.ff.interfaces.Sequence;
import cfar.utils.IO;
import java.io.File;
import java.io.IOException;
import java.net.InetAddress;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.Random;
import java.lang.Math;

import cfar.actors.Message;
import cfar.ff.fun.F0;
import cfar.ff.fun.F2;

import static cfar.ff.fun.Curry.*;


/**
 *
 * @author haoyun
 */
public class EvalSimp {

    public static List<Double> genTrajMap(Double iniX){
        List<Double> trajX=List.list(iniX);
        int timestep=10;
        double vn=0;
        double xn=iniX;
        double vhalf;
        double gamma=6.4114;
        double deltat=0.14;
        double delta=Math.sqrt((2*0.616*gamma)/(deltat/2));
        Random rand=new Random();
        double R=rand.nextGaussian()*delta;
        for(int i=1;i<timestep;i++){
            vhalf=vn+(deltat/2)*(-xn-gamma*vn+R);
            xn=xn+deltat*vhalf;
            R=rand.nextGaussian()*delta;
            vn=vhalf+deltat/2*(-xn-gamma*vn+R);
            trajX=trajX.snoc(xn);
        }
        return trajX;
    }

    public static Integer stateMap (Double x){
        int state=0;
        if(x>-3&x<-2)
            state=-1;
        else if(x>1&x<2)
            state=-2;
        else
            state=0;
        return state;
    }

    public static Integer stateRed (Integer s1, Integer s2){
        int state=0;
        if(s1==0|s2==0)
            state=s1+s2;
        else if(s1==-2&s2==-1)
            state=-2;
        else if(s1==-1&s2==-2)
            state=1;
        else if(s1==1|s2==1)
            state=1;
        else
            System.out.println("Algorithm goes run state="+s1+", "+s2);
        return state;
    }

    //===========================================================================

    public static F1 mapper = new F1<Double, Integer>() {

        public Integer f(Double a) {
            return stateMap(a);
        }
    };

    public static F2<Integer,Integer,Integer> reducer = new F2<Integer, Integer, Integer>() {

        public Integer f(Integer a, Integer b) {
            return stateRed(a,b);
        }
    };

    public static F2<String,String,Sequence<List,Node>> get_nodes = new F2<String, String, Sequence<List,Node>>() {

        public Sequence<List,Node> f(String dir, String suffix) {
            Sequence<List,Assoc2<InetAddress,Integer>> locs = IO.available_hosts(syncdir, suffix);
            List<Node> ns = List.nil();
            for(Assoc2<InetAddress,Integer> l : locs){
                try {
                    ns = ns.cons(new Node(l.$1, l.$2));
                } catch (IOException ex) {
                    Logger.getLogger(EvalSimp.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
            return ns;
        }
    };

    static String syncdir = "/tmp/cfar.sync"; // "/dscratch/cabdulwa/os/cfar.sync";
    static String suffix  = "cfar";

    public static void main(String[] args) throws IOException, InterruptedException {
//        if(args.length == 0)
            for (int i = 0; i < 10; i++)
                new Thread(new ActorServer(syncdir, suffix)).start();
//        else {
            List l = EvalSimp.genTrajMap(1.0);

            Sequence<List,Assoc2<InetAddress, Integer>> locs = IO.available_hosts(syncdir, suffix);
            List<Node> nodes = List.nil();
            for(Assoc2 a : locs)
                nodes = nodes.cons(new Node((InetAddress) a.$1, (Integer) a.$2));

//            List l2 = (List) Seq.distMap(nodes, mapper, l);

            F0 getnodes = curry(curry(get_nodes, syncdir), suffix);
            Integer r = Seq.distReduce(getnodes, reducer, l);
//
            for(Node n : nodes)
                n.tell(Message.stop);

            Thread.sleep(2000);
            System.out.println("mapped: " + r);
            System.exit(0);
//        }
    }
    

}
